circleci/aws-cli@3.1.5を使ったOIDC連携の自動デプロイをCIrcleCIのCI/CDに導入する
CX事業本部 Delivery 部のアベシです。
先日投稿したこちらのブログで、CircleCIのCI/CDでLocalStackを使ったテストを実行する方法紹介しました。
今回は特定のブランチへのmergeをトリガーにしてOIDC連携よるデプロイが走るようにしてみましたので、その際の設定や手順をご紹介したいと思います。
CircleCIとAWSとのOIDC連携には便利なOrbのcircleci/aws-cli@3.1.5
が使えますので導入してみました。
導入までの大まかな流れ
以下の流れでやっていきます。
- AWSでIDプロバイダーと信頼関係を持つIAMロールを作成
- CI/CDワークフローの設定ファイル(.circleci/config.yml)にデプロイのジョブを追加
- config.ymlに
aws-cli: circleci/aws-cli@3.1.5
とAWS CLIのインストールなどやってくれるコマンドのaws-cli/setup
を追加 - デプロイ先のリージョンを環境変数に設定
- 変更をmainブランチにマージしてCI/CDの結果がSuccessとなり、AWSにリソースがデプロイされていればOK
AWSでIDプロバイダーとプロバイダーと信頼関係の有るIAMロールを作成
AWS側でIDプロバイダーとIAMロールの作成については以下のブログに詳しく載っていますので参考にしてください。こちらのブログでは割愛します。
IDプロバイダーを作る際にCircleCIのOrganization ID
が必要になるので先にContext
を作成してください。
このやり方も上記のブログに載っていますので参考にしてください。
デプロイに関する修正をconfig.ymlに追加
それではここからはconfig.yml
の修正に入っていきます。
まずはmainブランチに変更がマージされた時にデプロイが走るようにします。
前回までのconfig.ymlはこちらから確認できます。この段階ではテストまでが可能でした。
修正を加えたconfig.ymlは以下となります。ハイライトした部分が修正部位となります。
version: 2.1 references: test_and_build_container: &test_and_build_container docker: - image: cimg/node:18.16.0 - image: localstack/localstack:2.0.1 environment: DOCKER_HOST: "unix:///var/run/docker.sock" DEBUG: "1" deploy_container: &deploy_container docker: - image: cimg/node:18.16.0 restore_npm_dependencies: &restore_npm_dependencies restore_cache: key: v1-dependencies-{{ .Branch }}-{{ checksum "package.json" }}-{{ checksum "package-lock.json" }} install_npm_dependencies: &install_npm_dependencies run: name: Install npm dependencies command: | set -x [[ -d node_modules ]] || npm ci save_npm_dependencies: &save_npm_dependencies save_cache: paths: - node_modules key: v1-dependencies-{{ .Branch }}-{{ checksum "package.json" }}-{{ checksum "package-lock.json" }} test_unit: &test_unit run: name: Test unit command: | set -x npm run unit-test deploy_to_aws: &deploy_to_aws run: name: Deploy to AWS command: | set -x npm run deploy jobs: test_and_build: <<: *test_and_build_container steps: - checkout - <<: *restore_npm_dependencies - <<: *install_npm_dependencies - <<: *save_npm_dependencies - <<: *test_unit deploy: <<: *deploy_container steps: - checkout - <<: *restore_npm_dependencies - <<: *install_npm_dependencies - <<: *save_npm_dependencies - <<: *deploy_to_aws workflows: test_workflows: jobs: - test_and_build: filters: branches: only: - /.*/ - deploy: requires: - test_and_build filters: branches: only: - main
config.ymlの修正部位の説明
references:
アンカー
デプロイのjobにおいても同じ内容のstepを一部使い回すために、各々をアンカーにして扱います。
例えば以下のnode_moduleのリストアの部分はrestore_npm_dependencies
の前に&
を付けて&restore_npm_dependencies
と記述することでアンカーとなります。
restore_npm_dependencies: &restore_npm_dependencies restore_cache: key: v1-dependencies-{{ .Branch }}-{{ checksum "package.json" }}-{{ checksum "package-lock.json" }}
エイリアス
アンカー&restore_npm_dependencies
を<<: *restore_npm_dependencies
と書くことでエイリアスとして使うことができます。
エイリアスはアンカーに指定したjob名の前に*
を付けて*restore_npm_dependencies
と記述します。
使用したい場所で、<<:
を付けて<<: *restore_npm_dependencies
と記述することでアンカーをエイリアスで呼び出せます。
アンカー化したjobを以下のように記述してstepsの中で呼び出すことができます。
jobs: test_and_build: <<: *test_and_build_container steps: - checkout - <<: *restore_npm_dependencies # アンカーをエイリアスで呼び出す
deploy_container: &deploy_container
デプロイ中に使用するCircleCIのNode.JS用イメージを定義します。
deploy_container: &deploy_container docker: - image: cimg/node:18.16.0
deploy_to_aws: &deploy_to_aws
デプロイのjobを定義します。 run deployはCDKデプロイコマンドをnpm スクリプト化したものでpackage.jsonに書いています。
deploy_to_aws: &deploy_to_aws run: name: Deploy to AWS command: | set -x npm run deploy
jobs:
node_noduleのリストア、インストール、キャッシュの保存の後にデプロイjobが作動するようにエイリアスを呼び出しています。
deploy: <<: *deploy_container steps: - checkout - <<: *restore_npm_dependencies - <<: *install_npm_dependencies - <<: *save_npm_dependencies - <<: *deploy_to_aws
workflows:
デプロイのワークフローをworkflow:に追加しています。 requires:にテストとビルドのワークフローを指定することで、テストとビルドが終わってからデプロイが走るようになります。 また、テストとビルドが失敗した場合はデプロイは走らないようになります。 filters:にはjobを実行する対象のブランチを指定します。今回はmainブランチのみに指定しています。その他のブランチへのマージやプッシュではデプロイは走りません。
deploy: requires: - test_and_build filters: branches: only: - main
OIDCに関するconfig.ymlの修正
OIDC連携によるデプロイを可能にするためconfig.ymlの修正を行います。 修正したconfig.ymlは以下の通りです。
version: 2.1 orbs: aws-cli: circleci/aws-cli@3.1.5 references: test_and_build_container: &test_and_build_container docker: - image: cimg/node:18.16.0 - image: localstack/localstack:2.0.1 environment: DOCKER_HOST: "unix:///var/run/docker.sock" DEBUG: "1" deploy_container: &deploy_container docker: - image: cimg/node:18.16.0 restore_npm_dependencies: &restore_npm_dependencies restore_cache: key: v1-dependencies-{{ .Branch }}-{{ checksum "package.json" }}-{{ checksum "package-lock.json" }} install_npm_dependencies: &install_npm_dependencies run: name: Install npm dependencies command: | set -x [[ -d node_modules ]] || npm ci save_npm_dependencies: &save_npm_dependencies save_cache: paths: - node_modules key: v1-dependencies-{{ .Branch }}-{{ checksum "package.json" }}-{{ checksum "package-lock.json" }} test_unit: &test_unit run: name: Test unit command: | set -x npm run unit-test aws_cli_setup: &aws_cli_setup aws-cli/setup: profile-name: WEB-IDENTITY-PROFILE role-arn: arn:aws:iam::**********:role/circleci-oidc-role role-session-name: deploy-session deploy_to_aws: &deploy_to_aws run: name: Deploy to AWS command: | set -x npm run deploy jobs: test_and_build: <<: *test_and_build_container steps: - checkout - <<: *restore_npm_dependencies - <<: *install_npm_dependencies - <<: *save_npm_dependencies - <<: *test_unit deploy: <<: *deploy_container steps: - checkout - <<: *restore_npm_dependencies - <<: *install_npm_dependencies - <<: *save_npm_dependencies - <<: *aws_cli_setup - <<: *deploy_to_aws workflows: test_workflows: jobs: - test_and_build: filters: branches: only: - /.*/ - deploy: requires: - test_and_build filters: branches: only: - main context: AWS-CONTEXT
修正したconfigの説明
orbs:
Orbは複数のコマンドをまとめいた再利用可能なパッケージです。
今回使用するcircleci/aws-cli@3.1.5
はaws-cliを使った便利な機能提供してくれます。
この機能(Command)の内のaws-cli/setup
を使うとOIDC用のIAMロールを使用してデプロイできます。
以下のリンク先の例を参考にreferences:の中にcommandを記述します。
aws-cli_setup: &aws-cli_setup aws-cli/setup: profile-name: WEB-IDENTITY-PROFILE role-arn: arn:aws:iam::***********:role/circleci-oidc-role role-session-name: deploy-session
role-arn
にはAWSのIDプロバイダーと信頼関係のあるIAMロールのARNを指定します。
リージョンの指定をしないとデプロイがコケますのでAWS_DEFAULT_REGION
という名前の環境変数にリージョンを設定しています。こちらにap-northeast-1を登録しました。
以下のようにdeployのワークフローのデプロイのjobの前にaws-cli_setup
のエイリアスを追加します。
deploy: <<: *deploy_container steps: - checkout - <<: *restore_npm_dependencies - <<: *install_npm_dependencies - <<: *save_npm_dependencies - <<: *aws_cli_setup - <<: *deploy_to_aws
workflows:
deploy:にcontextの名前を追加します。
context: AWS-CONTEXT
のように書きます。
contextを作成済みであればorganization settingsのContextsから見つけられます。
動作確認
実際にマージして動作確認を行います。 以下のようにステータスがsuccessとなればデプロイは成功です。
デプロイログの確認
以下のようなログが出力されており、デプロイしたスタックのARNが表示されています。
リソースの確認
CloudFormationのコンソールからデプロイしたスタックを確認します。 デプロイログに出力されたARNと同じARNのスタックが存在していることを確認できました。